package com.progenies.ecg.asm31.model.factory;

import org.objectweb.asm.Opcodes;

import com.progenies.ecg.model.FieldObject;
import com.progenies.ecg.model.ValueReference;
import com.progenies.ecg.model.factory.IObjectFieldFactory;

public class ObjectFieldFactoryASM31 implements IObjectFieldFactory {



	@Override
	public <T> FieldObject<T> createField(String name, Class<T> fieldType)
	{
		return createFieldWithDefaultValue(name, fieldType, null);
	}
	
	@Override
	public <T> FieldObject<T> createField(String name, Class<T> fieldType, boolean generateAccessorMethods)
	{
		return createFieldWithDefaultValue(name, fieldType, null, generateAccessorMethods);
	}
	
	@Override
	public <T> FieldObject<T> createFieldWithDefaultValue(String name, Class<T> fieldType,	T value) {
		return createFieldWithDefaultValue(name, fieldType, value, false);
	}

	
	@Override
	public <T> FieldObject<T> createFieldWithDefaultValue(String name, Class<T> fieldType,	T value, boolean generateAccessorMethods) {
		if(name==null)
			throw new IllegalArgumentException("name cannot be null");
		if(fieldType==null)
			throw new IllegalArgumentException("fieldType cannot be null");
		
		FieldObjectASM31<T> tmp=new FieldObjectASM31<T>(name, fieldType, new int[] {Opcodes.ACC_PROTECTED}, generateAccessorMethods, generateAccessorMethods);
		tmp.setValue(value);
		return tmp;
	}

	

	@Override
	public <T> FieldObject<T> createFieldArray(String name, Class<T> fieldType) {
		return createFieldArray(name, fieldType, false);
	}
	
	


	@Override
	public <T> FieldObject<T> createFieldArray(String name, Class<T> fieldType,	boolean generateAccessorMethods) {
		return createFieldArray(name, fieldType, -1, generateAccessorMethods);
	}

	@Override
	public <T> FieldObject<T> createFieldArrayWithDefaultValue(String name, Class<T> fieldType,	T value)
	{
		return createFieldArrayWithDefaultValue(name, fieldType, value, false);
	}

	@Override
	public <T> FieldObject<T> createFieldArrayWithDefaultValue(String name, Class<T> fieldType,	T value, boolean generateAccessorMethods) {
		if(fieldType==null || !fieldType.isArray())
			throw new RuntimeException("The field type is not of an array class");
		
		FieldObject<T> field=createField(name, fieldType, generateAccessorMethods);
		field.setValue(value);
		return field;
	}
	
	
	@Override
	public <T> FieldObject<T> createFieldArray(String name, Class<T> fieldType,	ValueReference<?> varReference[])
	{
		return createFieldArray(name, fieldType, varReference, false);
	}

	@Override
	public <T> FieldObject<T> createFieldArray(String name, Class<T> fieldType,	ValueReference<?> varReference[], boolean generateAccessorMethods) {
		if(fieldType==null || !fieldType.isArray())
			throw new RuntimeException("The field type is not of an array class");
		
		FieldObject<T> field=createField(name, fieldType, generateAccessorMethods);
		field.setVarReference(varReference);
		return field;
	}
	
	@Override
	public <T> FieldObject<T> createFieldArray(String name, Class<T> fieldType,	ValueReference<?> varReference[][])
	{
		return createFieldArray(name, fieldType, varReference, false);
	}

	@Override
	public <T> FieldObject<T> createFieldArray(String name, Class<T> fieldType,	ValueReference<?> varReference[][], boolean generateAccessorMethods) {
		if(fieldType==null || !fieldType.isArray())
			throw new RuntimeException("The field type is not of an array class");
		
		FieldObject<T> field=createField(name, fieldType, generateAccessorMethods);
		field.setMatrixVarReference(varReference);
		return field;
	}

	@Override
	public <T> FieldObject<T> createFieldArray(String name, Class<T> fieldType,	int arraySize) {
		return createFieldArray(name, fieldType, arraySize, false);
	}

	@Override
	public <T> FieldObject<T> createFieldArray(String name, Class<T> fieldType,	int arraySize, boolean generateAccessorMethods)
	{
		if(fieldType==null || !fieldType.isArray())
			throw new RuntimeException("The field type is not of an array class");
		
		FieldObject<T> field=createField(name, fieldType, generateAccessorMethods);
		field.setArrayDimensions(arraySize>=0?new int[] {arraySize}:null);
		field.setInitialize(arraySize>=0);
		return field;
	}
	
	
	@Override
	public <T> FieldObject<T> createFieldArray(String name, Class<T> fieldType,	int[] matrixSize) {
		return createFieldArray(name, fieldType, matrixSize, false);
	}

	@Override
	public <T> FieldObject<T> createFieldArray(String name, Class<T> fieldType,	int[] matrixSize, boolean generateAccessorMethods)
	{
		if(fieldType==null || !fieldType.isArray())
			throw new RuntimeException("The field type is not of an array class");
		
		FieldObject<T> field=createField(name, fieldType, generateAccessorMethods);
		field.setArrayDimensions(matrixSize);
		field.setInitialize(true);
		return field;
	}

}
